package base

import (
	"context"
	"github.com/zeromicro/go-zero/core/logc"
	frameworkRecover "payme3000/framework/recover"
	"time"
)

type (
	// IJob 单次任务, 仅执行一次
	IJob interface {
		IComponent

		Run(context.Context) // 任务回调, 即实际的任务逻辑所在

		getKey() string                                  // 返回唯一标识
		schedule(context.Context, func(context.Context)) // 调度任务
		wait()                                           // 等待任务调度完成
		placeholderJob()
	}

	// Job IJob的基础实现
	Job struct {
		Component

		Key string // 唯一标识
	}
)

// Run 由继承Job的自定义Job各自实现
func (j *Job) Run(_ context.Context) {}

func (j *Job) getKey() string {
	return j.Key
}

// schedule 调度任务
func (j *Job) schedule(ctx context.Context, job func(context.Context)) {
	defer j.AddDone()()

	startTime := time.Now().UnixMilli()

	// 执行任务, 要确保回调即使panic也不会影响服务
	frameworkRecover.WithRecover(func() {
		job(ctx)
	})

	endTime := time.Now().UnixMilli()

	logc.Infof(ctx, "job has been run with key:%s, duration:%d(ms)", j.Key, endTime-startTime)

	return
}

func (j *Job) wait() {
	j.Wg.Wait()
}

func (j *Job) placeholderJob() {}
